<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>完整3D编辑器</title>
    <style>
        body { 
            margin: 0; 
            overflow: hidden; 
            touch-action: none;
            font-family: Arial, sans-serif;
        }
        #ui {
            position: fixed;
            top: 10px;
            left: 10px;
            background: rgba(255,255,255,0.9);
            padding: 10px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            z-index: 100;
            display: grid;
            grid-template-columns: repeat(4, auto);
            gap: 5px;
        }
        .tool-btn {
            padding: 8px 12px;
            border: none;
            border-radius: 4px;
            background: #2196F3;
            color: white;
            cursor: pointer;
            transition: all 0.3s;
            font-size: 14px;
            min-width: 60px;
        }
        .tool-btn:hover {
            background: #0d8bf2;
        }
        .tool-btn.active {
            background: #1976D2;
            box-shadow: 0 0 5px rgba(0,0,0,0.2);
        }
        #colorPicker {
            width: 30px;
            height: 30px;
            padding: 0;
            border: 2px solid #ddd;
            cursor: pointer;
        }
        #status {
            position: fixed;
            bottom: 10px;
            left: 10px;
            color: white;
            background: rgba(0,0,0,0.7);
            padding: 5px 10px;
            border-radius: 4px;
            font-size: 12px;
        }
        #textureUpload {
            display: none;
        }
    </style>
</head>
<body>
    <div id="ui">
        <button class="tool-btn" id="transformBtn" onclick="setMode('transform')">移动</button>
        <button class="tool-btn" id="sculptBtn" onclick="setMode('sculpt')">雕刻</button>
        <button class="tool-btn" id="paintBtn" onclick="setMode('paint')">绘画</button>
        <input type="color" id="colorPicker" value="#ff0000" onchange="painter.setColor(this.value)">
        <button class="tool-btn" onclick="addPrimitive('box')">立方体</button>
        <button class="tool-btn" onclick="addPrimitive('sphere')">球体</button>
        <button class="tool-btn" onclick="document.getElementById('textureUpload').click()">贴图</button>
        <button class="tool-btn" onclick="exportModel()">导出</button>
        <button class="tool-btn" onclick="deleteObject()">删除</button>
    </div>
    <div id="status">场景已加载</div>
    <input type="file" id="textureUpload" accept="image/*">

    <!-- 使用官方CDN加载Three.js库 -->
    <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/build/three.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/exporters/GLTFExporter.js"></script>

    <script>
        // 核心变量
        let scene, camera, renderer, controls;
        let currentMode = 'transform';
        let selectedObject = null;
        let transformControls = null;
        const painter = new PaintingSystem();
        let isDragging = false;

        // 绘画系统
        class PaintingSystem {
            constructor() {
                this.isPainting = false;
                this.lastUV = null;
                this.brush = {
                    size: 20,
                    hardness: 0.7,
                    color: new THREE.Color('#ff0000')
                };
            }

            setColor(hex) {
                this.brush.color.set(hex);
                updateStatus(`画笔颜色设置为: ${hex}`);
            }

            startPaint(uv) {
                if (!selectedObject?.material?.map) {
                    updateStatus("错误: 请先添加纹理");
                    return;
                }
                this.isPainting = true;
                this.lastUV = uv.clone();
                this.paintAtUV(uv);
            }

            continuePaint(uv) {
                if (!this.isPainting || !this.lastUV) return;
                
                const steps = Math.ceil(this.lastUV.distanceTo(uv) * 100);
                for (let i = 0; i <= steps; i++) {
                    const t = i / steps;
                    const interpUV = new THREE.Vector2().lerpVectors(this.lastUV, uv, t);
                    this.paintAtUV(interpUV);
                }
                this.lastUV = uv.clone();
            }

            paintAtUV(uv) {
                const texture = selectedObject.material.map;
                const canvas = texture.image;
                const ctx = canvas.getContext('2d');
                
                const x = uv.x * canvas.width;
                const y = (1 - uv.y) * canvas.height;
                
                ctx.globalCompositeOperation = 'source-over';
                ctx.fillStyle = this.createBrushGradient(x, y, ctx);
                ctx.beginPath();
                ctx.arc(x, y, this.brush.size, 0, Math.PI * 2);
                ctx.fill();
                
                texture.needsUpdate = true;
            }

            createBrushGradient(x, y, ctx) {
                const gradient = ctx.createRadialGradient(
                    x, y, 0,
                    x, y, this.brush.size
                );
                gradient.addColorStop(0, `rgba(${
                    Math.floor(this.brush.color.r * 255)},${
                    Math.floor(this.brush.color.g * 255)},${
                    Math.floor(this.brush.color.b * 255)},1)`);
                gradient.addColorStop(this.brush.hardness, `rgba(${
                    Math.floor(this.brush.color.r * 255)},${
                    Math.floor(this.brush.color.g * 255)},${
                    Math.floor(this.brush.color.b * 255)},0)`);
                return gradient;
            }

            endPaint() {
                this.isPainting = false;
                this.lastUV = null;
            }
        }

        // 初始化场景
        function init() {
            // 创建场景
            scene = new THREE.Scene();
            scene.background = new THREE.Color(0x222222);

            // 创建相机
            camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.set(5, 5, 5);

            // 创建渲染器
            renderer = new THREE.WebGLRenderer({ 
                antialias: true,
                powerPreference: "high-performance"
            });
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.setPixelRatio(window.devicePixelRatio);
            document.body.appendChild(renderer.domElement);

            // 添加光源
            const light = new THREE.DirectionalLight(0xffffff, 1);
            light.position.set(5, 5, 5);
            scene.add(light);
            scene.add(new THREE.AmbientLight(0x404040));

            // 添加网格地面
            const grid = new THREE.GridHelper(20, 20, 0x888888, 0x444444);
            scene.add(grid);

            // 初始化控制器
            controls = new THREE.OrbitControls(camera, renderer.domElement);
            controls.enableDamping = true;
            controls.dampingFactor = 0.05;

            // 设置事件监听
            setupEventListeners();
            setMode('transform');

            // 添加默认立方体
            addPrimitive('box');
            updateStatus("场景初始化完成");
        }

        // 事件监听设置
        function setupEventListeners() {
            const canvas = renderer.domElement;
            
            // 鼠标事件
            canvas.addEventListener('mousedown', onPointerStart);
            canvas.addEventListener('mousemove', onPointerMove);
            canvas.addEventListener('mouseup', onPointerEnd);
            
            // 触摸事件
            canvas.addEventListener('touchstart', onPointerStart);
            canvas.addEventListener('touchmove', onPointerMove);
            canvas.addEventListener('touchend', onPointerEnd);

            // 窗口大小调整
            window.addEventListener('resize', onWindowResize);

            // 纹理上传
            document.getElementById('textureUpload').addEventListener('change', handleTextureUpload);
        }

        // 窗口大小调整处理
        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        // 设置当前模式
        function setMode(mode) {
            currentMode = mode;
            document.querySelectorAll('.tool-btn').forEach(btn => 
                btn.classList.remove('active'));
            document.getElementById(`${mode}Btn`).classList.add('active');
            
            if (transformControls) {
                scene.remove(transformControls);
                transformControls = null;
            }
            
            if (mode === 'transform' && selectedObject) {
                showTransformControls();
            }
            updateStatus(`模式: ${getModeName(mode)}`);
        }

        // 获取模式名称
        function getModeName(mode) {
            const names = {
                transform: '物体变换',
                sculpt: '顶点雕刻',
                paint: '纹理绘制'
            };
            return names[mode] || mode;
        }

        // 添加基本几何体
        function addPrimitive(type) {
            const geometry = createGeometry(type);
            const material = createPaintableMaterial();
            const mesh = new THREE.Mesh(geometry, material);
            mesh.position.y = 0.5;
            scene.add(mesh);
            selectObject(mesh);
            updateStatus(`已添加: ${type}`);
        }

        // 创建几何体
        function createGeometry(type) {
            switch(type) {
                case 'box': return new THREE.BoxGeometry(1, 1, 1);
                case 'sphere': return new THREE.SphereGeometry(0.5, 32, 32);
                default: throw new Error("未知几何体类型");
            }
        }

        // 创建可绘制材质
        function createPaintableMaterial() {
            const canvas = document.createElement('canvas');
            canvas.width = 1024;
            canvas.height = 1024;
            const ctx = canvas.getContext('2d');
            ctx.fillStyle = '#ffffff';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            const texture = new THREE.CanvasTexture(canvas);
            texture.wrapS = THREE.RepeatWrapping;
            texture.wrapT = THREE.RepeatWrapping;
            
            return new THREE.MeshStandardMaterial({
                map: texture,
                roughness: 0.5,
                metalness: 0
            });
        }

        // 指针开始事件
        function onPointerStart(event) {
            isDragging = true;
            try {
                const intersects = getIntersects(event);
                if (intersects.length > 0) {
                    selectObject(intersects[0].object);
                    
                    switch(currentMode) {
                        case 'transform':
                            showTransformControls();
                            break;
                        case 'sculpt':
                            if (!selectedObject.geometry.isBufferGeometry) {
                                updateStatus("错误: 该几何体不支持雕刻");
                                return;
                            }
                            updateSculpting(intersects[0]);
                            break;
                        case 'paint':
                            painter.startPaint(intersects[0].uv);
                            break;
                    }
                }
            } catch (error) {
                handleError(error);
            }
        }

        // 指针移动事件
        function onPointerMove(event) {
            if (!isDragging) return;
            try {
                const intersects = getIntersects(event);
                if (intersects.length === 0) return;

                switch(currentMode) {
                    case 'sculpt':
                        updateSculpting(intersects[0]);
                        break;
                    case 'paint':
                        painter.continuePaint(intersects[0].uv);
                        break;
                }
            } catch (error) {
                handleError(error);
            }
        }

        // 指针结束事件
        function onPointerEnd() {
            isDragging = false;
            painter.endPaint();
        }

        // 选择物体
        function selectObject(object) {
            selectedObject = object;
            updateStatus(`已选择: ${object.geometry.type}`);
        }

        // 显示变换控制器
        function showTransformControls() {
            if (!selectedObject) return;
            
            transformControls = new THREE.TransformControls(camera, renderer.domElement);
            transformControls.setMode('translate');
            transformControls.attach(selectedObject);
            scene.add(transformControls);

            transformControls.addEventListener('dragging-changed', (event) => {
                controls.enabled = !event.value;
            });

            transformControls.addEventListener('mouseUp', () => {
                selectedObject.geometry.attributes.position.needsUpdate = true;
            });
        }

        // 更新雕刻效果
        function updateSculpting(intersect) {
            const geometry = selectedObject.geometry;
            const vertices = geometry.attributes.position.array;
            const radius = 0.5;
            const strength = 0.15;

            for (let i = 0; i < vertices.length; i += 3) {
                const vertex = new THREE.Vector3(vertices[i], vertices[i+1], vertices[i+2]);
                const distance = intersect.point.distanceTo(vertex);
                
                if (distance < radius) {
                    const falloff = Math.pow(1 - (distance / radius), 2);
                    const delta = intersect.face.normal
                        .clone()
                        .multiplyScalar(strength * falloff);
                    
                    vertices[i] += delta.x;
                    vertices[i+1] += delta.y;
                    vertices[i+2] += delta.z;
                }
            }
            
            geometry.attributes.position.needsUpdate = true;
            geometry.computeVertexNormals();
        }

        // 删除物体
        function deleteObject() {
            if (selectedObject) {
                scene.remove(selectedObject);
                if (transformControls) scene.remove(transformControls);
                selectedObject = null;
                updateStatus("已删除选中物体");
            }
        }

        // 导出模型
        function exportModel() {
            const exporter = new THREE.GLTFExporter();
            exporter.parse(scene, (gltf) => {
                const blob = new Blob([JSON.stringify(gltf)], {type: 'model/gltf+json'});
                const link = document.createElement('a');
                link.href = URL.createObjectURL(blob);
                link.download = `model_${Date.now()}.gltf`;
                link.click();
            }, { binary: false });
        }

        // 获取射线交点
        function getIntersects(event) {
            const rect = renderer.domElement.getBoundingClientRect();
            const clientX = event.touches?.[0]?.clientX || event.clientX;
            const clientY = event.touches?.[0]?.clientY || event.clientY;
            
            const mouse = new THREE.Vector2(
                ((clientX - rect.left) / rect.width) * 2 - 1,
                -((clientY - rect.top) / rect.height) * 2 + 1
            );

            const raycaster = new THREE.Raycaster();
            raycaster.setFromCamera(mouse, camera);
            return raycaster.intersectObjects(scene.children);
        }

        // 处理纹理上传
        function handleTextureUpload(event) {
            const file = event.target.files[0];
            if (!file) return;

            const reader = new FileReader();
            reader.onload = function(e) {
                const texture = new THREE.TextureLoader().load(e.target.result);
                texture.wrapS = THREE.RepeatWrapping;
                texture.wrapT = THREE.RepeatWrapping;
                
                if (selectedObject) {
                    selectedObject.material.map = texture;
                    selectedObject.material.needsUpdate = true;
                    updateStatus("贴图已更新");
                }
            };
            reader.readAsDataURL(file);
        }

        // 更新状态显示
        function updateStatus(text) {
            document.getElementById('status').textContent = text;
        }

        // 错误处理
        function handleError(error) {
            console.error(error);
            updateStatus(`错误: ${error.message}`);
            isDragging = false;
            painter.endPaint();
        }

        // 启动场景
        init();

        // 动画循环
        function animate() {
            requestAnimationFrame(animate);
            controls.update();
            renderer.render(scene, camera);
        }
        animate();
    </script>
</body>
</html>